﻿using Edge.Extensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text.RegularExpressions;
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Globalization;

namespace Edge.Utilities.Tests
{
    /// <summary>
    ///This is a test class for StringExtensionsTest and is intended
    ///to contain all StringExtensionsTest Unit Tests
    ///</summary>
    [TestClass()]
    public class StringExtensionsTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion
        
        /// <summary>
        ///A test for Base64Decode
        ///</summary>
        [TestMethod()]
        public void Base64DecodeTest()
        {
            string s = "SGVsbG8sIFdvcmxkIQ==";
            string expected = "Hello, World!";
            string actual;
            actual = s.Base64Decode();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Base64Encode
        ///</summary>
        [TestMethod()]
        public void Base64EncodeTest()
        {
            string s = "Hello, World!";
            string expected = "SGVsbG8sIFdvcmxkIQ=="; 
            string actual;
            actual = s.Base64Encode();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for CharacterInstanceCount
        ///</summary>
        [TestMethod()]
        public void CharacterInstanceCountTest()
        {
            string value = "Hello, World!";
            string character = "l";
            int expected = 3;
            int actual;
            actual = value.CharacterInstanceCount(character);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Contains
        ///</summary>
        [TestMethod()]
        public void ContainsTest()
        {
            string s = "Hello, World!";
            string subString = "hello";
            bool caseSensitive = false;
            bool expected = true;
            bool actual;
            actual = s.Contains(subString, caseSensitive);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ContainsWords
        ///</summary>
        [TestMethod()]
        public void ContainsWordsTest()
        {
            string s = "This is a test sentence.";
            string[] wordArray = new string[] { "test", "sentence" };

            MatchCollection actual = StringExtensions.ContainsWords(s, wordArray);

            int matchCount = 0;

            foreach (Match match in actual)
            {
                GroupCollection groups = match.Groups;

                if (groups[0].Success == true)
                    matchCount++;
            }

            Assert.AreEqual(2, matchCount);
        }

        /// <summary>
        ///A test for Encrypt
        ///</summary>
        [TestMethod()]
        public void EncryptDecryptTest()
        {
            string s = "Hello, World!";
            string key = "mykey";
            string encrypted = s.Encrypt(key);
            string decrypted = encrypted.Decrypt(key);
            string expected = "Hello, World!";
            string actual;
            actual = decrypted;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for EndsWithAny
        ///</summary>
        [TestMethod()]
        public void EndsWithAnyTest()
        {
            string s = "Hello, World!";
            List<string> values = new List<string>();
            values.AddRange("hello", "!", "World");
            bool expected = true;
            bool actual;
            actual = s.EndsWithAny(values);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for FilterWords
        ///</summary>
        [TestMethod()]
        public void FilterWordsTest()
        {
            string s = "This is a test sentence.";
            string[] filterWords = new string[] { " is a", " sentence" };
            string expected = "This test.";
            string actual;
            actual = s.FilterWords(filterWords);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for FilterWords
        ///</summary>
        [TestMethod()]
        public void FilterWordsTest2()
        {
            string s = "This is a test sentence.";
            char mask = '*';
            string[] filterWords = new string[] { "test" };
            string expected = "This is a **** sentence.";
            string actual;
            actual = s.FilterWords(mask, filterWords);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for FindBetween
        ///</summary>
        [TestMethod()]
        public void FindBetweenTest()
        {
            string s = "Hello, <span>World</span>!";
            string startString = "<span>";
            string endString = "</span>";
            string expected = "World";
            MatchCollection collection = s.FindBetween(startString, endString);
            string actual = "";
            if (collection.Count > 0)
            {
                actual = collection[0].ToString();
            }
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for FindBetween
        ///</summary>
        [TestMethod()]
        public void FindBetweenTest2()
        {
            string s = "public static int DoStuff(";
            string startString = " ";
            string endString = "(";
            string expected = "DoStuff";
            MatchCollection collection = s.FindBetween(startString, endString);
            string actual = "";
            if (collection.Count > 0)
            {
                actual = collection[0].ToString();
            }
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ForcePrefix
        ///</summary>
        [TestMethod()]
        public void ForcePrefixTest()
        {
            string s = " World!";
            string prefix = "Hello,";
            string expected = "Hello, World!";
            string actual;
            actual = s.ForcePrefix(prefix);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ForceSuffix
        ///</summary>
        [TestMethod()]
        public void ForceSuffixTest()
        {
            string s = "Hello, ";
            string suffix = "World!"; 
            string expected = "Hello, World!";
            string actual;
            actual = s.ForceSuffix(suffix);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for FormatPhoneNumber
        ///</summary>
        [TestMethod()]
        public void FormatPhoneNumberTest()
        {
            string value = "4065555555";
            string expected = "(406) 555-5555";
            string actual;
            actual = value.FormatPhoneNumber();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for IsDate
        ///</summary>
        [TestMethod()]
        public void IsDateTest()
        {
            string value = "12/31/1971";
            bool expected = true;
            bool actual;
            actual = value.IsDate();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for IsEmpty
        ///</summary>
        [TestMethod()]
        public void IsEmptyTest()
        {
            string value = "Hello, World!";
            bool expected = false;
            bool actual;
            actual = value.IsEmpty();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for IsInteger
        ///</summary>
        [TestMethod()]
        public void IsIntegerTest()
        {
            string s = "42";
            bool expected = true;
            bool actual;
            actual = s.IsNumeric();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for IsInteger
        ///</summary>
        [TestMethod()]
        public void IsIntegerTest2()
        {
            string s = "Hello, World!";
            bool expected = false;
            bool actual;
            actual = s.IsNumeric();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for IsValidCreditCardNumber
        ///</summary>
        [TestMethod()]
        public void IsValidCreditCardNumberTest()
        {
            Assert.IsTrue("1111-2323-2312-3434".IsValidCreditCardNumber());
            Assert.IsTrue("1234343425262837".IsValidCreditCardNumber());
            Assert.IsTrue("1111 2323 2312 3434".IsValidCreditCardNumber());
            Assert.IsFalse("1111 2323 2312-3434".IsValidCreditCardNumber());
            Assert.IsFalse("34323423".IsValidCreditCardNumber());
            Assert.IsFalse("1111-2323-23122-3434".IsValidCreditCardNumber());
        }

        /// <summary>
        ///A test for IsValidEmailAddress
        ///</summary>
        [TestMethod()]
        public void IsValidEmailAddressTest()
        {
            Assert.IsTrue("yellowdog@someemail.uk".IsValidEmailAddress());
            Assert.IsTrue("yellow.444@email4u.co.uk".IsValidEmailAddress());
            Assert.IsFalse("adfasdf".IsValidEmailAddress());
            Assert.IsFalse("asd@asdf".IsValidEmailAddress());
        }

        /// <summary>
        ///A test for IsValidIPAddress
        ///</summary>
        [TestMethod()]
        public void IsValidIPAddressTest()
        {
            string s = "1.0.45.256";
            bool expected = false;
            bool actual;
            actual = s.IsValidIPAddress();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for IsValidIPAddress
        ///</summary>
        [TestMethod()]
        public void IsValidIPAddressTest2()
        {
            string s = "1.0.45.25";
            bool expected = true;
            bool actual;
            actual = s.IsValidIPAddress();
            Assert.AreEqual(expected, actual);
        }
        
        /// <summary>
        ///A test for IsValidUrl
        ///</summary>
        [TestMethod()]
        public void IsValidUrlTest()
        {
            Assert.IsFalse("www.codeproject.com".IsValidUrl());
            Assert.IsTrue("http://www.codeproject.com".IsValidUrl());
            Assert.IsTrue("https://www.codeproject.com/#some_anchor".IsValidUrl());
            Assert.IsTrue("https://localhost".IsValidUrl());
            Assert.IsTrue("http://www.abcde.nf.net/signs-banners.jpg".IsValidUrl());
            Assert.IsTrue("http://aa-bbbb.cc.bla.com:80800/test/test/test.aspx?dd=dd&id=dki".IsValidUrl());
            Assert.IsFalse("http:wwwcodeprojectcom".IsValidUrl());
            Assert.IsFalse("http://www.code project.com".IsValidUrl());
        }

        /// <summary>
        ///A test for Left
        ///</summary>
        [TestMethod()]
        public void LeftTest()
        {
            string s = "Hello, World!";
            int count = 5;
            string expected = "Hello";
            string actual;
            actual = s.Left(count);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for MaskCreditCard
        ///</summary>
        [TestMethod()]
        public void MaskCreditCardTest()
        {
            string s = "1234567890123456";
            char maskCharacter = 'X';
            string expected = "XXXXXXXXXXXX3456";
            string actual;
            actual = StringExtensions.MaskCreditCard(s, maskCharacter);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Mid
        ///</summary>
        [TestMethod()]
        public void MidTest()
        {
            string s = "Hello, World!";
            int index = 2;
            int count = 4;
            string expected = "llo,";
            string actual;
            actual = s.Mid(index, count);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for PadLeft
        ///</summary>
        [TestMethod()]
        public void PadLeftTest1()
        {
            string s = "Hello, World!";
            string pad = " How are you?";
            string expected = "Hello, World! How are you?";
            string actual;
            actual = s.PadLeft(pad);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for PadLeft
        ///</summary>
        [TestMethod()]
        public void PadLeftTest2()
        {
            string s = "Hello, World!";
            string pad = " How are you?";
            int totalWidth = 17;
            bool cutOff = true;
            string expected = "Hello, World! How";
            string actual;
            actual = s.PadLeft(pad, totalWidth, cutOff);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for PadRight
        ///</summary>
        [TestMethod()]
        public void PadRightTest1()
        {
            string s = "How are you?";
            string pad = "Hello, World! ";
            string expected = "Hello, World! How are you?";
            string actual;
            actual = s.PadRight(pad);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for PadRight
        ///</summary>
        [TestMethod()]
        public void PadRightTest()
        {
            string s = "How are you?";
            string pad = "Hello, World! ";
            int totalWidth = 17;
            bool cutOff = true;
            string expected = "HelloHow are you?";
            string actual;
            actual = s.PadRight(pad, totalWidth, cutOff);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for RemoveDuplicateWords
        ///</summary>
        [TestMethod()]
        public void RemoveDuplicateWordsTest()
        {
            string s = "To be or not to be - that is the question.";
            string expected = "To be or not - that is the question.";
            string actual;
            actual = s.RemoveDuplicateWords();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for RemoveNewLines
        ///</summary>
        [TestMethod()]
        public void RemoveNewLinesTest1()
        {
            string s = "Hello, \r\nWorld!";
            string expected = "Hello, World!";
            string actual;
            actual = s.RemoveNewLines();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for RemoveNewLines
        ///</summary>
        [TestMethod()]
        public void RemoveNewLinesTest()
        {
            string s = "Hello,\r\nWorld!";
            bool addSpace = true;
            string expected = "Hello, World!";
            string actual;
            actual = s.RemoveNewLines(addSpace);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for RemovePrefix
        ///</summary>
        [TestMethod()]
        public void RemovePrefixTest()
        {
            string s = "Hello, World!";
            string prefix = "Hello, ";
            string expected = "World!";
            string actual;
            actual = s.RemovePrefix(prefix);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for RemoveSpaces
        ///</summary>
        [TestMethod()]
        public void RemoveSpacesTest()
        {
            string input = "yellow dog" + Environment.NewLine + "black cat";
            string expected = "yellowdog" + Environment.NewLine + "blackcat";
            string actual = input.RemoveSpaces();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for RemoveSuffix
        ///</summary>
        [TestMethod()]
        public void RemoveSuffixTest()
        {
            string s = "Hello, World!";
            string suffix = ", World!";
            string expected = "Hello";
            string actual;
            actual = s.RemoveSuffix(suffix);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Replace
        ///</summary>
        [TestMethod()]
        public void ReplaceTest()
        {
            string s = "Hello, World!";
            string oldString = "world";
            string newString = "Dude";
            bool caseSensitive = false;
            string expected = "Hello, Dude!";
            string actual;
            actual = s.Replace(oldString, newString, caseSensitive);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Reverse
        ///</summary>
        [TestMethod()]
        public void ReverseTest()
        {
            string s = "Hello, World!";
            string expected = "!dlroW ,olleH";
            string actual;
            actual = s.Reverse();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Right
        ///</summary>
        [TestMethod()]
        public void RightTest()
        {
            string s = "Hello, World!";
            int count = 6;
            string expected = "World!";
            string actual;
            actual = s.Right(count);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for SentenceCase
        ///</summary>
        [TestMethod()]
        public void SentenceCaseTest()
        {
            string s = "This Is Just a Test.";
            string expected = "This is just a test.";
            string actual;
            actual = s.SentenceCase();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Slice
        ///</summary>
        [TestMethod()]
        public void SliceTest()
        {
            string s = "Hello, World!";
            int startIndex = 0;
            int endIndex = 5;
            string expected = "Hello";
            string actual;
            actual = s.Slice(startIndex, endIndex);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for SlugDecode
        ///</summary>
        [TestMethod()]
        public void SlugDecodeTest()
        {
            string s = "This_is_a_test.";
            string expected = "This is a test.";
            string actual;
            actual = s.SlugDecode();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for SlugEncode
        ///</summary>
        [TestMethod()]
        public void SlugEncodeTest()
        {
            string s = "This is a test.";
            string expected = "This_is_a_test.";
            string actual;
            actual = s.SlugEncode();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Split
        ///</summary>
        [TestMethod()]
        public void SplitTest1()
        {
            string s = "one, two, three";
            string delimiter = ",";
            string expected = " two";
            string actual;
            actual = s.Split(delimiter)[1];
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Split
        ///</summary>
        [TestMethod()]
        public void SplitTest()
        {
            string s = "one, two, three";
            string delimiter = ",";
            bool trimTokens = true;
            string expected = "two";
            string actual;
            actual = s.Split(delimiter, trimTokens)[1];
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for StartsWithAny
        ///</summary>
        [TestMethod()]
        public void StartsWithAnyTest()
        {
            string s = "Hello, World!";
            List<string> values = new List<string>();
            values.Add("Goodbye");
            values.Add("Hello");
            bool expected = true;
            bool actual;
            actual = s.StartsWithAny(values);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for StripTags
        ///</summary>
        [TestMethod()]
        public void StripTagsTest()
        {
            string s = "<body>Hello, World!</body>";
            string expected = "Hello, World!";
            string actual;
            actual = s.StripTags();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for TitleCase
        ///</summary>
        [TestMethod()]
        public void TitleCaseTest()
        {
            string s = "On the waterfront";
            string expected = "On the Waterfront";
            string actual;
            actual = s.TitleCase();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for TitleCase
        ///</summary>
        [TestMethod()]
        public void TitleCaseTest2()
        {
            string s = "On the waterfront";
            bool ignoreShortWords = false;
            string expected = "On The Waterfront";
            string actual;
            actual = s.TitleCase(ignoreShortWords);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ToBoolean
        ///</summary>
        [TestMethod()]
        public void ToBooleanTest()
        {
            string s = "False";
            bool expected = false;
            bool actual;
            actual = s.ToBoolean();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ToByteArray
        ///</summary>
        [TestMethod()]
        public void ToByteArrayTest()
        {
            string s = "Hello, World!";
            byte[] converted = s.ToByteArray();
            Assert.AreEqual(s, converted.ByteArrayToString());
        }

        /// <summary>
        ///A test for ToColor
        ///</summary>
        [TestMethod()]
        public void ToColorTest()
        {
            string s = "#ffffff";
            Color expected = Color.FromArgb(255, 255, 255);
            Color actual;
            actual = s.ToColor();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ToDecimal
        ///</summary>
        [TestMethod()]
        public void ToDecimalTest()
        {
            string s = "5";
            Decimal expected = 5;
            Decimal actual;
            actual = s.ToDecimal();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ToInt16
        ///</summary>
        [TestMethod()]
        public void ToInt16Test()
        {
            string s = "5";
            long expected = 5;
            long actual;
            actual = s.ToInt16();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ToInt32
        ///</summary>
        [TestMethod()]
        public void ToInt32Test()
        {
            string s = "10";
            long expected = 10;
            long actual;
            actual = s.ToInt64();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ToInt64
        ///</summary>
        [TestMethod()]
        public void ToInt64Test()
        {
            string s = "294967295";
            long expected = 294967295;
            long actual;
            actual = s.ToInt64();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for TrimIntraWords
        ///</summary>
        [TestMethod()]
        public void TrimIntraWordsTest()
        {
            string s = "Hello,  World!";
            string expected = "Hello, World!";
            string actual;
            actual = s.TrimIntraWords();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Truncate
        ///</summary>
        [TestMethod()]
        public void TruncateTest()
        {
            string s = "Hello, World!";
            int maxLength = 5;
            string expected = "He...";
            string actual;
            actual = s.Truncate(maxLength);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for WordCount
        ///</summary>
        [TestMethod()]
        public void WordCountTest()
        {
            string s = "Hello, World!";
            int expected = 2;
            int actual;
            actual = s.WordCount();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for WordInstanceCount
        ///</summary>
        [TestMethod()]
        public void WordInstanceCountTest()
        {
            string s = "Hello, World! How are you doing today?";
            string word = "How";
            int expected = 1;
            int actual;
            actual = StringExtensions.WordInstanceCount(s, word);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for WordWrap
        ///</summary>
        [TestMethod()]
        public void WordWrapTest()
        {
            string s = "Hello, World! How are you doing today?";
            int charCount = 9;
            string expected = "Hello, " + Environment.NewLine +
                              "World! How are " + Environment.NewLine +
                              "you doing " + Environment.NewLine +
                              "today?";
            string actual;
            actual = s.WordWrap(charCount);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for WordWrap
        ///</summary>
        [TestMethod()]
        public void WordWrapTest1()
        {
            string s = "Hello, World! How are you doing today?";
            int charCount = 9;
            bool cutOff = true;
            string expected = "Hello, Wo" + Environment.NewLine +
                              "rld! How " + Environment.NewLine +
                              "are you d" + Environment.NewLine +
                              "oing toda" + Environment.NewLine +
                              "y?";
            string actual;
            actual = s.WordWrap(charCount, cutOff);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for WordWrap
        ///</summary>
        [TestMethod()]
        public void WordWrapTest2()
        {
            string s = "Hello, World! How are you doing today?";
            int charCount = 9;
            bool cutOff = false;
            string breakText = Environment.NewLine;
            string expected = "Hello, " + Environment.NewLine +
                              "World! How are " + Environment.NewLine +
                              "you doing " + Environment.NewLine +
                              "today?";
            string actual;
            actual = s.WordWrap(charCount, cutOff, breakText);
            Assert.AreEqual(expected, actual);
        }
    }
}
